home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1995-11-25 | 26.1 KB | 860 lines |
- IMPLEMENTATION MODULE EasyWindow;
-
- FROM SYSTEM IMPORT TSIZE, VAL,ADDRESS,SHIFT,SHORT,ADR,BYTE;
-
- FROM Storage IMPORT ALLOCATE,DEALLOCATE;
-
- FROM GEMVDIbase IMPORT PxyArrayType, BigPxyArrayType, TextAttrArrayType;
-
- FROM VDIRasters IMPORT CopyRasterOpaque,MFDBType,MFDBptr;
-
- FROM VDIControls IMPORT SetClipping;
-
- FROM VDIAttribs IMPORT SetFillStyle,SetFillColour,SetFillInteriorStyle,
- SetGraphicTextColour,SetGraphicTextEffects;
-
- FROM VDIInquires IMPORT InquireFillAttributes,InquireTextAttributes;
-
- FROM VDIOutputs IMPORT DrawBar,GraphicText;
-
- FROM GEMAESbase IMPORT WindowRedraw, WindowTopped, WindowClosed, WindowFulled,
- WindowArrowed, WindowHorizSlided, WindowVertSlided,
- WindowSized, WindowMoved, WindowNewTop, WindowKind,
- WindowName, WindowInfo, WorkXYWH, CurrXYWH, PrevXYWH,
- FullXYWH, WindowHorizSlide, WindowVertSlide, Top,
- FirstXYWH, NextXYWH, HorizSliderSize, VertSliderSize,
- WindowScreen,White,Black,EndUpdate,BeginUpdate,WCWork,
- WCBorder;
-
- FROM AES IMPORT GrafMouse,FormDialogue,WindowFind,WindowGet,WindowDelete,
- WindowClose,WindowSet,WindowUpdate,WindowCalc,WindowOpen,
- GrafGrowBox,GrafShrinkBox,GrafHandle,WindowCreate,FormAlert;
-
-
- VAR
- WC,HC,WB,HB : INTEGER;
- handle : INTEGER;
- Nil2Max : INTEGER;
-
-
- PROCEDURE TerminateWindows;
- VAR w: INTEGER;
- BEGIN
- FOR w := 1 TO maxwindow DO
- IF windowlist[w] # NIL THEN
- IF windowlist[w]^.opened THEN
- WindowClose(w);
- END(*IF*);
- DEALLOCATE(windowlist[w]);
- WindowDelete(w);
- END(*IF*);
- END(*FOR*);
- w:=SetGraphicTextColour(handle,Black);
- w:=SetGraphicTextEffects(handle,VAL(INTEGER,NoEffects));
-
- END TerminateWindows;
-
-
- PROCEDURE createWindow (VAR u: window;
- x, y, w, h: INTEGER;
- parts: WindowElements;
- title: ARRAY OF CHAR;
- textwindow: BOOLEAN;
- rdp: RedrawProcType);
- VAR win :windowtype;
- i,wx,wy,ww,wh: INTEGER;
- t : wstring;
-
-
- BEGIN
- IF HIGH(title)>78 THEN
- FOR i:= 0 TO 78 DO
- t[i]:=title[i]
- END(*FOR*);
- t[79]:=0C
- ELSE
- FOR i:= 0 TO HIGH(title) DO
- t[i]:=title[i]
- END(*FOR*);
- t[HIGH(title)+1]:=0C
- END(*IF*);
- IF (w=0) OR (h=0) THEN
- WindowGet(0,WorkXYWH,wx,wy,ww,wh);
- u:=WindowCreate(VAL(INTEGER,parts),wx,wy,ww,wh);
- WindowCalc(WCWork,VAL(INTEGER,parts),wx,wy,ww,wh,x,y,w,h);
- WindowCalc(WCBorder,VAL(INTEGER,parts),x,y,w,h,wx,wy,ww,wh);
- ELSE
- WindowCalc(WCBorder,VAL(INTEGER,parts),x,y,w,h,wx,wy,ww,wh);
- u:=WindowCreate(VAL(INTEGER,parts),wx,wy,ww,wh);
- END(*IF*);
- IF (u>0) AND (u<maxwindow) THEN
- win.handle:=u;
- win.max.x:=wx;
- win.max.y:=wy;
- win.max.w:=ww;
- win.max.h:=wh;
- win.work.x:=x;
- win.work.y:=y;
- win.work.w:=w;
- win.work.h:=h;
- win.total.x:=wx;
- win.total.y:=wy;
- win.total.w:=ww;
- win.total.h:=wh;
- win.min.x:=wx;
- win.min.y:=wy;
- win.min.w:=10*WC;
- win.min.h:=6*HC;
- win.elements:=parts;
- win.fulled:=FALSE;
- win.opened:=FALSE;
- win.ontop:=FALSE;
- win.text:=textwindow;
- win.grow:=growbox;
- win.snap:=Snap;
- IF textwindow THEN
- win.allignX:=WC;
- win.allignY:=HC;
- win.scrollX:=WC;
- win.scrollY:=HC;
- ELSE
- win.allignX:=AllignX;
- win.allignY:=AllignY;
- win.scrollX:=WC;
- win.scrollY:=HC;
- END(*IF*);
- win.row:=1;win.col:=1;
- win.maxrow:=1;
- win.maxcol:=1;
- win.colour:=White;
- win.InteriorStyle:=1C;
- win.FillStyle:=1C;
- win.textcolour:=Black;
- win.texteffects:=NoEffects;
- win.redrawproc:=rdp;
- win.title:=t;
- win.info:=0C;
- win.reference:=NIL;
- ALLOCATE(windowlist[u],TSIZE(windowtype));
- windowlist[u]^:=win;
- SetTitle(u,title);
- ELSE
- t:="[3][Zu viele Fenster offen][Abbruch]";
- x:=FormAlert(1,t);
- END(*IF*);
- END createWindow;
-
- (* Erzeugt die im AES und in diesem Modul notwendigen Datenstrukturen
- zur Verwaltung eines Fensters, das jedoch noch nicht gezeichnet
- wird.
-
- x, y, w und h beschreiben die maximale Grösse des äusseren Fenster-
- randes. Sind w oder h gleich 0, so wird die Grösse des Desktops
- ohne Menüleiste übernommen.
-
- "parts" ist ein Set aus den gewünschten Fensterelementen.
-
- "title" ist der Fenstertitel.
-
- "textwindow" soll bei Textfenstern auf TRUE gesetzt werden,
- der Fensterursprung wird dann an das Textraster angepaßt.
-
- "rdp" ist die Redraw-Prozedur, also die Prozedur, die den Inhalt
- des Fensters zeichnet. Sie wird beim Aufruf der Prozedur "DoRedraw"
- (siehe unten) so oft aufgerufen wird, bis die Rechteckliste, die
- die sichtbaren Teile des Fensters angibt, abgearbeitet worden ist.
- An "rdp" wird beim Aufruf ein Rechteck übergeben, das die neu
- zu zeichnende Fläche angibt. Wurde beim Aufruf von "DoRedraw"
- der Paramter "clip" auf FALSE gesetzt, muss "rdp" alle Ausgaben
- selbst auf diese Fläche begrenzen, was die Ausgabe vor allem bei
- Text stark beschleunigen kann, aber bei teilweise verdeckten Fen-
- stern kaum durchführbar ist. Beim Zeichnen von Objektbäumen wird
- das Begrenzungsrechteck direkt beim "ObjectDraw"-Aufruf angegeben.
- *)
-
-
- PROCEDURE clearWindow (u: window );
- VAR win : windowtype;
- rect :rectangle;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- WindowGet(u,WorkXYWH,rect.x,rect.y,rect.w,rect.h);
- rect.x:=0;rect.y:=0;
- clearrect(u,rect);
- END(*IF*);
- END(*IF*);
- END clearWindow;
-
- PROCEDURE clearrect (u: window ; rect: rectangle);
- VAR win : windowtype;
- pxy : PxyArrayType;
- Bpxy :BigPxyArrayType;
- c,s,x,y,w,h:INTEGER;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- WindowGet(u,WorkXYWH,x,y,w,h);
- rect.x:=rect.x+x;
- rect.y:=rect.y+y;
- RectToPxy(rect,pxy);
- (* Derzeitige Füllatribute und Farben erfragen *)
- InquireFillAttributes(handle,Bpxy);
- MouseOff;
- c:=SetFillColour(handle,win.colour);
- s:=SetFillStyle (handle,VAL(INTEGER,win.FillStyle));
- s:=SetFillInteriorStyle (handle,VAL(INTEGER,win.InteriorStyle));
- DrawBar(handle,pxy);
- (* Füll-Atribute u. -Farbe wierherstellen *)
- c:=SetFillColour(handle,Bpxy[1]);
- s:=SetFillStyle (handle,Bpxy[2]);
- s:=SetFillInteriorStyle (handle,Bpxy[0]);
- MouseOn;
- END(*IF*);
- END(*IF*);
- END clearrect;
-
- (* Löscht einen Rechteckbereich innerhalb des Fensters "u" in
- Fensterkoordinaten *)
-
- PROCEDURE closeWindow (u: window );
- VAR win : windowtype;
- x,y,w,h :INTEGER;
-
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
-
- IF win.opened THEN
- WindowGet(u,CurrXYWH,x,y,w,h);
- IF win.grow THEN
- GrafShrinkBox(x,y,WC,HC,x,y,w,h)
- END(*IF*);
- WindowClose(u);
- END(*IF*);
- win.opened:=FALSE;
- win.ontop:=FALSE;
- windowlist[u]^:=win;
- END(*IF*);
- END closeWindow;
-
- PROCEDURE deleteWindow (VAR u: window );
- VAR win : windowtype;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- WindowClose(u);
- END(*IF*);
- WindowDelete(u);
- DEALLOCATE(windowlist[u]);
- windowlist[u]:= NIL;
- u:=-1
- END(*IF*);
- END deleteWindow ;
-
- PROCEDURE fullWindow (u: window );
- VAR win : windowtype;
- x,y,w,h :INTEGER;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF ~win.fulled THEN
- IF win.grow THEN
- WindowGet(u,CurrXYWH,x,y,w,h);
- GrafGrowBox(x,y,w,h, win.max.x,win.max.y,win.max.w,win.max.h);
- END(*IF*);
- WindowSet(u,CurrXYWH,win.max.x,win.max.y,win.max.w,win.max.h);
- win.fulled := TRUE
- ELSE
- WindowGet(u,PrevXYWH,x,y,w,h);
- IF (x=win.max.x) AND (y=win.max.y) AND
- (w=win.max.w) AND (h=win.max.h) THEN
- x:=win.min.x;
- y:=win.min.y;
- w:=win.min.w;
- h:=win.min.h;
- END(*IF*);
- IF win.grow THEN
- GrafShrinkBox(x,y,w,h, win.max.x,win.max.y,win.max.w,win.max.h);
- END(*IF*);
- WindowSet(u,CurrXYWH,x,y,w,h);
- win.fulled := FALSE
- END(*IF*);
- win.opened:=TRUE;
- WindowGet(u,CurrXYWH,x,y,w,h);
- win.total.x:=x;
- win.total.y:=y;
- win.total.w:=w;
- win.total.h:=h;
- WindowGet(u,WorkXYWH,x,y,w,h);
- win.work.x :=x;
- win.work.y :=y;
- win.work.w :=w;
- win.work.h :=h;
- windowlist[u]^:=win;
- END(*IF*);
- END fullWindow;
-
- PROCEDURE SnapWindow(u:window;VAR x,y,w,h:INTEGER);
- (* Verkleinert das Fenster bei Verschiebungen so
- das es vollständig auf dem Desktop zu sehen ist*)
- VAR win:windowtype;
- x0,y0,w0,h0 :INTEGER;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- WindowGet(0,WorkXYWH,x0,y0,w0,h0);
- IF (x+win.min.w)>(w0) THEN
- x:=x0+w0-win.min.w
- END(*IF*);
- IF (y+win.min.h)>(h0) THEN
- y:=y0+h0-win.min.h
- END(*IF*);
- IF (x+w) > (x0+w0) THEN
- w:=x0+w0-x;
- END(*IF*);
- IF (y+h) > (y0+h0) THEN
- h:=y0+h0-y;
- END(*IF*);
- END(*IF*);
- END SnapWindow;
-
- PROCEDURE AlignWindow(u:window;VAR x,y,w,h:INTEGER);
- (* Passt das Fenster bei Verschiebungen an den
- Snap-Wert an *)
- VAR win : windowtype;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- x:=x+SHIFT(win.allignX,-1)+1;
- x:= win.allignX*(x DIV win.allignX);
- y:=y+SHIFT(win.allignY,-1)+1;
- y:= win.allignY*(y DIV win.allignY)
- END(*IF*);
- END AlignWindow;
-
-
- PROCEDURE openWindow (u: window ; x, y, w, h: INTEGER);
- VAR win:windowtype;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF (w=0) OR (h=0) THEN
- IF win.grow THEN
- GrafGrowBox(x,y,w,h, win.total.x,win.total.y,win.total.w,win.total.h);
- END(*IF*);
- WindowOpen(u,win.total.x,win.total.y,win.total.w,win.total.h);
- ELSE
- IF win.grow THEN
- GrafGrowBox(x+(w DIV 2),y+(h DIV 2),WC,HC,x,y,w,h)
- END(*IF*);
- WindowOpen(u,x,y,w,h);
- END(*IF*);
- WindowGet(u,CurrXYWH,x,y,w,h);
- win.total.x:=x;
- win.total.y:=y;
- win.total.w:=w;
- win.total.h:=h;
- win.opened:=TRUE;
- WindowGet(u,WorkXYWH,x,y,w,h);
- win.work.x :=x;
- win.work.y :=y;
- win.work.w :=w;
- win.work.h :=h;
- windowlist[u]^:=win;
- WindowGet(u,Top,u,y,w,h);
- topWindow(u);
- END(*IF*);
- END openWindow;
-
- PROCEDURE setWindow (u:window ; x, y, w, h: INTEGER);
- VAR win : windowtype;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF (win.allignX#1) OR (win.allignY#1) THEN
- AlignWindow(u,x,y,w,h)
- END(*IF*);
- IF win.snap THEN SnapWindow(u,x,y,w,h) END(*IF*);
- IF win.min.w>w THEN w:=win.min.w END(*IF*);
- IF win.min.h>h THEN h:=win.min.h END(*IF*);
- WindowSet(u,CurrXYWH,x,y,w,h);
- win.total.x:=x;
- win.total.y:=y;
- win.total.w:=w;
- win.total.h:=h;
- WindowGet(u,WorkXYWH,x,y,w,h);
- win.work.x :=x;
- win.work.y :=y;
- win.work.w :=w;
- win.work.h :=h;
- windowlist[u]^:=win;
- END(*IF*);
- END setWindow;
-
- PROCEDURE topWindow (u: window );
- VAR win : windowtype;
- i : INTEGER;
-
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- WindowSet(u,Top,u,0,0,0);
- win.opened:=TRUE;
- win.ontop:=TRUE;
- windowlist[u]^:=win;
- FOR i:= 0 TO maxwindow DO
- IF windowlist[i] # NIL THEN
- win:=windowlist[i]^;
- IF win.handle#u THEN
- win.ontop:=FALSE;
- windowlist[i]^:=win;
- END(*IF*);
- END(*IF*);
- END(*FOR*);
- END(*IF*);
- END topWindow;
-
- PROCEDURE MouseOn;
- BEGIN
- GrafMouse(257,NIL)
- END MouseOn;
-
- PROCEDURE MouseOff;
- BEGIN
- GrafMouse(256,NIL)
- END MouseOff;
-
- (* Vor Ausgaben auf den Bildschirm muss die Maus ausgeschaltet werden,
- da sonst das Maussymbol überschrieben wird und bei der nächsten
- Bewegung der Maus der alte, zuvor von der Maus verdeckte Bildschirm-
- inhalt wieder restauriert wird. Alle Prozeduren in diesem Modul, die
- den Bildschirm verändern, schalten die Maus während der Ausgabe aus.
- Während des Aufrufs der vom Benutzer bereitgestellten Redraw-Prozedur
- beim Abarbeiten der Rechteckliste in "DoRedraw" wird die Maus eben-
- falls ausgeschaltet, ruft der Benutzer dagegen selbst seine Redraw-
- Prozedur auf oder benutzt er die weiter unten beschriebenen Textaus-
- gabeprozeduren, muss er sich selbst um die Maus kümmern.
-
- Achtung: Ein- und Ausschalten der Maus wird vom Betriebssystem
- mitgezählt. Wird die Maus mehrmals ausgeschaltet, muß
- sie genausooft wieder eingeschaltet werden, damit sie
- sichtbar wird. Wird die Maus zu oft eingeschaltet, dann
- entstehen beim Bewegen von Fenstern und Schiebern Schmutz-
- effekte.
- *)
-
- PROCEDURE High(a:ADDRESS):INTEGER;
- VAR r : RECORD CASE : BOOLEAN OF
- TRUE : w: ADDRESS;
- |FALSE : h,l :INTEGER;
- END(*CASE*);
- END(*RECORD*);
- BEGIN
- r.w:=a;
- RETURN r.h
- END High;
-
- PROCEDURE Low(a:ADDRESS):INTEGER;
- VAR r:RECORD CASE : BOOLEAN OF
- TRUE : w : ADDRESS;
- |FALSE : h,l : INTEGER;
- END(*CASE*);
- END(*RECORD*);
- BEGIN
- r.w:=a;
- RETURN r.l
- END Low;
-
-
- PROCEDURE SetInfo (u: window ; s: ARRAY OF CHAR);
- VAR win :windowtype;
- t :wstring;
- i :INTEGER;
- BEGIN
- IF HIGH(s)>78 THEN
- FOR i:= 0 TO 78 DO
- t[i]:=s[i]
- END(*FOR*);
- t[79]:=0C
- ELSE
- FOR i:= 0 TO HIGH(s) DO
- t[i]:=s[i]
- END(*FOR*);
- t[HIGH(s)+1]:=0C
- END(*IF*);
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- win.info:=t;
- windowlist[u]^:=win;
- WindowSet(u,WindowInfo,High(ADR(windowlist[u]^.info)),
- Low(ADR(windowlist[u]^.info)),0,0);
- END(*IF*);
- END SetInfo;
-
- (* Schreibt einen Text in die Info-Zeile des Fensters *)
-
-
- PROCEDURE SetTitle (u: window ; s: ARRAY OF CHAR);
- VAR win :windowtype;
- t : wstring;
- i :INTEGER;
- BEGIN
- IF HIGH(s)>78 THEN
- FOR i:= 0 TO 78 DO
- t[i]:=s[i]
- END(*FOR*);
- t[79]:=0C
- ELSE
- FOR i:= 0 TO HIGH(s) DO
- t[i]:=s[i]
- END(*FOR*);
- t[HIGH(s)+1]:=0C
- END(*IF*);
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- win.title:=t;
- windowlist[u]^:=win;
- WindowSet(u,WindowName,High(ADR(windowlist[u]^.title)),
- Low(ADR(windowlist[u]^.title)),0,0);
- END(*IF*);
- END SetTitle;
-
- (* Schreibt einen Text in die Titel-Zeile des Fensters. Der Text
- bleibt beim Schliessen erhalten und wird beim Öffnen wieder
- angezeigt
- *)
-
- PROCEDURE SetHorSlider (u: window ; wpos, wsize, total: INTEGER);
- VAR win :windowtype;
- SliderSize,SliderPos :INTEGER;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- MouseOff;
- SliderSize:=wsize*1000 DIV total;
- IF total <= wsize THEN
- SliderPos := 0;
- ELSE
- SliderPos:=wpos*1000 DIV total
- END(*IF*);
- WindowSet(u,WindowHorizSlide,SliderPos,0,0,0);
- WindowSet(u,HorizSliderSize,SliderSize,0,0,0);
- MouseOn;
- win.row:=wpos;win.maxrow :=total;
- windowlist[u]^:=win;
- END(*IF*);
- END SetHorSlider;
-
- (* siehe "SetVertSlider", setzt den horizontalen Schieber entsprechend
- der horizontalen Position des Fensters im Gesamtdokument.
- *)
-
- PROCEDURE SetVertSlider (u: window ; wpos, wsize, total: INTEGER);
- VAR win :windowtype;
- SliderSize,SliderPos :INTEGER;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- MouseOff;
- SliderSize:=wsize*1000 DIV total;
- IF total <= wsize THEN
- SliderPos := 0;
- ELSE
- SliderPos:=wpos*1000 DIV total
- END(*IF*);
- WindowSet(u,WindowHorizSlide,SliderPos,0,0,0);
- WindowSet(u,HorizSliderSize,SliderSize,0,0,0);
- MouseOn;
- win.col:=wpos;win.maxcol :=total;
- windowlist[u]^:=win;
- END(*IF*);
- END SetVertSlider;
-
- (* Berechnet die korrekte Position und -grösse des vertikalen
- Schiebers aus den Parametern, die die vertikale Position des
- Fensters im Gesamtdokument beschreiben, und setzt den Schieber.
- Die Schieber müssen, falls vorhanden, nach jeder Veränderung
- der Fenstergrösse oder des Fensterinhalts neu gesetzt werden.
-
- Bedeutung der Parameter:
-
- wpos: Anfangsposition des Fensters im Gesamtdokument
- wsize: Grösse des im Fenster dargestellten Teils des Gesamtdokuments
- total: Grösse des Gesamtdokuments
- *)
-
-
-
- PROCEDURE copyrect (u: window ; source, dest: rectangle);
- VAR win : windowtype;
- XYWH : BigPxyArrayType;
- Screen1MFDB,Screen2MFDB : MFDBType;
- x,y,w,h : INTEGER;
-
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- MouseOff;
- WindowGet(u,WorkXYWH,x,y,w,h);
- source.x:=source.x+x;source.y:=source.y+y;
- dest.x:=dest.x+x;dest.y:=dest.y+y;
- Screen1MFDB.pointer:=0D;
- Screen1MFDB.width:=source.w;
- Screen1MFDB.height:=source.h;
- Screen1MFDB.format:=1;
- Screen1MFDB.rsrvd1:=0; Screen1MFDB.rsrvd2:=0;
- XYWH[0]:=source.x; XYWH[1]:=source.y; XYWH[2]:=source.w+source.x; XYWH[3]:=source.h+source.y;
- XYWH[4]:=dest.x;XYWH[5]:=dest.y; XYWH[6]:=dest.w+dest.x;XYWH[7]:=dest.h+dest.y;
- Screen2MFDB.pointer:=0D;
- Screen2MFDB.width:=dest.w;
- Screen2MFDB.height:=dest.h;
- Screen2MFDB.format:=1;
- Screen2MFDB.rsrvd1:=0; Screen2MFDB.rsrvd2:=0;
- CopyRasterOpaque(handle,3,XYWH,ADR(Screen1MFDB),ADR(Screen2MFDB));
- MouseOn;
- END(*IF*);
- END(*IF*);
- END copyrect;
-
- (* Kopiert innerhalb eines Fensters den Rechteckbereich "source" in
- den Rechteckbereich "dest" (Koordinaten relativ zum Fensterursprung
- links oben). Der freiwerdende Bereich von "source" muss bei Bedarf
- gelöscht werden. Mit dieser Prozedur lassen sich Scroll-,
- Insert- und Deletefunktionen in Textfenstern realisieren *)
-
-
- PROCEDURE scrollup (u: window );
- VAR win : windowtype;
- r1,r2,r3 : rectangle;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- r1:=win.work; r2:=win.work;
- r1.x:=win.scrollX; r1.y:=win.scrollY;
- r1.w:=r1.w-win.scrollX; r1.h:=r1.h-win.scrollY;
- r2.x:=0;r2.y:=0;
- r2.w:=r2.w-win.scrollX; r2.h:=r2.h-win.scrollY;
- r3.x:=win.work.w-win.scrollX; r3.y:=win.work.w-win.scrollY;
- r3.w:=win.scrollY; r3.h:=win.scrollY;
- copyrect(u,r1,r2);
- clearrect(u,r3);
- win.row:=win.row+1;
- windowlist[u]^:=win;
- END(*IF*);
- END(*IF*);
- END scrollup;
-
- (* Schiebt den Inhalt eines Textfensters eine Zeile nach oben, die
- oberste Zeile verschwindet, die unterste wird gelöscht. "row"
- wird auf "maxrow", "col" auf 0 gesetzt *)
-
-
- PROCEDURE scrolldown (u: window );
- VAR win : windowtype;
- r1,r2,r3 : rectangle;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- r1:=win.work; r2:=win.work;
- r1.x:=win.scrollX; r1.y:=win.scrollY;
- r1.w:=r1.w-win.scrollX; r1.h:=r1.h-win.scrollY;
- r2.x:=0;r2.y:=0;
- r2.w:=r2.w-win.scrollX; r2.h:=r2.h-win.scrollY;
- r3.x:=0;r3.y:=0;
- r3.w:=win.scrollX; r3.h:=win.scrollY;
- copyrect(u,r2,r1);
- clearrect(u,r3);
- IF win.row >0 THEN
- win.row:=win.row-1
- ELSE
- win.row:=0;
- END(*IF*);
- windowlist[u]^:=win;
- END(*IF*);
- END(*IF*);
- END scrolldown;
-
- (* Schiebt den Inhalt eines Textfenster eine Zeile nach unten, die
- unterste Zeile verschwindet, die oberste wird gelöscht. "row"
- und "col" werden auf 0 gesetzt *)
-
-
- PROCEDURE DrawCursor (u:window ; row, col: INTEGER);
- VAR win : windowtype;
- XYWH : BigPxyArrayType;
- ScreenMFDB : MFDBType;
- x,y,w,h : INTEGER;
-
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- MouseOff;
- WindowGet(u,WorkXYWH,x,y,w,h);
- ScreenMFDB.pointer:=0D;
- ScreenMFDB.width:=WC;
- ScreenMFDB.height:=HC;
- ScreenMFDB.format:=1;
- ScreenMFDB.rsrvd1:=0; ScreenMFDB.rsrvd2:=0;
- XYWH[0]:=x+row*WC; XYWH[1]:=y+row*HC; XYWH[2]:=XYWH[0]+HC; XYWH[3]:=XYWH[1]+WC;
- XYWH[4]:=XYWH[0]; XYWH[5]:=XYWH[1]; XYWH[6]:=XYWH[2]; XYWH[7]:=XYWH[3];
- CopyRasterOpaque(handle,12,XYWH,ADR(ScreenMFDB),ADR(ScreenMFDB));
- MouseOn;
- END(*IF*);
- END(*IF*);
- END DrawCursor;
-
- (* Zeichnet ein Rechteck in der Grösse eines Zeichenfeldes an die
- angegebene Stelle innerhalb des Fensters. Da alle Pixel inver-
- tiert werden, nimmt ein zweiter Aufruf mit denselben Parametern
- den Cursor wieder weg. *)
-
-
- PROCEDURE WriteStr (u: window ; row, col: INTEGER; s: ARRAY OF CHAR);
- VAR win : windowtype;
- i,x,y,w,h: INTEGER;
- Attributes : TextAttrArrayType;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
- IF win.opened THEN
- MouseOff;
- WindowGet(u,WorkXYWH,x,y,w,h);
- x:=x+row*WC;
- y:=y+col*HC;
- InquireTextAttributes(handle,Attributes);
- i:=SetGraphicTextColour(handle,win.textcolour);
- i:=SetGraphicTextEffects(handle,VAL(INTEGER,win.texteffects));
- GraphicText(handle,x,y,s);
- i:=SetGraphicTextColour(handle,Attributes[1]);
- i:=SetGraphicTextEffects(handle,0);
- MouseOn;
- END(*IF*);
- END(*IF*);
- END WriteStr;
-
- (* Gibt einen String ab der durch "row" (Zeile) und "col" (Spalte)
- angegebenen Stelle aus. Zeile und Spalte beziehen sich auf den
- Arbeitsbereich des Fensters. Das Zeichen in der linken oberen
- Ecke hat die Koordinaten (0,0). *)
-
-
- PROCEDURE WriteTextBlock (u: window ; row, col: INTEGER;
- adr: ADDRESS; count: INTEGER);
-
- (* Wie "WriteStr", nur wird der auszugebende String durch die Adresse
- des ersten Zeichens und die Länge angegeben
- *)
- END WriteTextBlock;
-
- PROCEDURE WriteTextBuffer (u: window ; adr: ADDRESS;
- count, offset: INTEGER);
-
- (* Gibt den ab der Adresse "adr" liegenden Text ins Fenster "u" ab
- der Position (0,0) aus, bis entweder 0C im Text auftritt, "count"
- erreicht wird oder das Fenster voll ist. Als Zeilenende wird lf
- erkannt, cr wird ignoriert. Falls "offset" > 0, werden die ersten
- "offset" Zeichen in jeder Zeile übersprungen, so dass sich hori-
- zontale Fensterverschiebungen realisieren lassen. Diese Prozedur
- eignet sich gut für das Redrawing von Textfensterpuffern.
- *)
- END WriteTextBuffer;
-
-
- PROCEDURE RectToPxy (VAR rect: rectangle; VAR pxy: PxyArrayType);
-
- BEGIN
- pxy[0]:=rect.x;
- pxy[1]:=rect.y;
- pxy[2]:=rect.x+rect.w;
- pxy[3]:=rect.y+rect.h;
- END RectToPxy;
-
- PROCEDURE Intersect(r1:rectangle;VAR r2 :rectangle):BOOLEAN;
- VAR r : rectangle;
-
- PROCEDURE Min(a,b:INTEGER ):INTEGER;
- BEGIN
- IF a<b THEN RETURN a ELSE RETURN b END(*IF*);
- END Min;
-
- PROCEDURE Max(a,b:INTEGER ):INTEGER;
- BEGIN
- IF a>b THEN RETURN a ELSE RETURN b END(*IF*);
- END Max;
-
- BEGIN
- r.w:=Min(r1.x+r1.w,r2.x+r2.w); r.h:=Min(r1.y+r1.h,r2.y+r2.h);
- r.x:=Max(r1.x,r2.x);r.y:=Max(r1.y,r2.y);
- r2:=r; r2.w:=r.w-r.x; r2.h:=r.h-r.y;
- RETURN ((r.w>r.x) AND (r.h>r.y))
- END Intersect;
-
- PROCEDURE DoRedraw (u: window ; x, y, w, h: INTEGER; clip: BOOLEAN);
- VAR r,r1 : rectangle;
- pxy :PxyArrayType;
- win : windowtype;
- BEGIN
- IF windowlist[u] # NIL THEN
- win:=windowlist[u]^;
-
- r1.x:=x;r1.y:=y;r1.h:=h;r1.w:=w;
- MouseOff;
- WindowUpdate(BeginUpdate);
- WindowGet(u,FirstXYWH,r.x,r.y,r.w,r.h);
- WHILE (r.w>0) AND (r.h>0) DO
- IF Intersect(r1,r) THEN
- r.w:=r.w-1; r.h:=r.h-1;
- RectToPxy(r,pxy);
- IF clip THEN
- SetClipping(handle,1,pxy);
- END(*IF*);
- win.redrawproc(u,r);
- END(*IF*);
- WindowGet(u,NextXYWH,r.x,r.y,r.w,r.h);
- END(*WHILE*);
- pxy[0]:=0; pxy[1]:=0; pxy[2]:=0; pxy[3]:=0;
- SetClipping(handle,0,pxy);
- WindowUpdate(EndUpdate);
- MouseOn;
- END(*IF*);
- END DoRedraw;
-
- (* Holt sich von AES die Rechteckliste des Fensters w, schneidet die
- erhaltenen Rechtecke mit dem Desktop und der als Parameter über-
- gebenen Fläche und führt dann die erforderliche Anzahl von Auf-
- rufen der Redraw-Prozedur, die beim Create-Aufruf angegeben wurde,
- aus. "DoRedraw" ist somit die Aktion auf eine Redraw-Message. Mit
- "clip" kann angegeben werden, ob "DoRedraw" selbst den Clipping-
- Aufruf für VDI-Funktionen durchführen soll. In jedem Fall wird
- während des Ablaufs von "DoRedraw" das Window-Update-Flag gesetzt
- und die Maus ausgeschaltet.
- *)
-
- PROCEDURE wp (u: window ): windowptr;
- BEGIN
- RETURN windowlist[u];
- END wp;
-
-
-
-
-
- BEGIN
- FOR Nil2Max := -1 TO maxwindow DO
- windowlist[Nil2Max]:= NIL
- END(*FOR*);
- handle:=GrafHandle(WC,HC,WB,HB);
- growbox:=TRUE;
- Snap:=FALSE;
- AllignX :=1;
- AllignY :=1;
- END EasyWindow.
-